home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / CPP / WFC010.ZIP / SRC / CBUBBLE.CPP next >
C/C++ Source or Header  |  1995-12-07  |  6KB  |  244 lines

  1. #include <wfc.h>
  2. #pragma hdrstop
  3.  
  4. /*
  5. ** Author: Samuel R. Blackburn
  6. ** CI$: 76300,326
  7. ** Internet: sammy@sed.csc.com
  8. **
  9. ** You can use it any way you like as long as you don't try to sell it.
  10. **
  11. ** Any attempt to sell WFC in source code form must have the permission
  12. ** of the original author. You can produce commercial executables with
  13. ** WFC but you can't sell WFC.
  14. **
  15. ** Copyright, 1995, Samuel R. Blackburn
  16. **
  17. ** $Workfile: $
  18. ** $Revision: $
  19. ** $Modtime: $
  20. */
  21.  
  22. #if defined( _DEBUG )
  23. #undef THIS_FILE
  24. static char BASED_CODE THIS_FILE[] = __FILE__;
  25. #define new DEBUG_NEW
  26. #endif
  27.  
  28. CString CBubble::m_ClassName = "";
  29.  
  30. CFont CBubble::m_Font;
  31.  
  32. DWORD CBubble::m_Height = 0;
  33.  
  34. IMPLEMENT_DYNAMIC( CBubble, CWnd );
  35.  
  36. CBubble::CBubble()
  37. {
  38.    m_FontSize = (-8);
  39.    m_Created  = FALSE;
  40. }
  41.  
  42. CBubble::CBubble( int font_size )
  43. {
  44.    m_Created  = FALSE;
  45.    m_FontSize = font_size;
  46. }
  47.  
  48. CBubble::~CBubble()
  49. {
  50. }
  51.  
  52. BOOL CBubble::Create()
  53. {
  54.    if ( m_ClassName == "" )
  55.    {
  56.       CBrush brush;
  57.  
  58.       TRY
  59.       {
  60.          brush.CreateSolidBrush( LIGHT_YELLOW );
  61.       }
  62.       CATCH( CResourceException, e )
  63.       {
  64.          return( FALSE );
  65.       }
  66.       END_CATCH
  67.  
  68.       m_ClassName = ::AfxRegisterWndClass( CS_BYTEALIGNCLIENT | CS_SAVEBITS | CS_HREDRAW | CS_VREDRAW, 0, (HBRUSH) brush.Detach() );
  69.  
  70.       if ( m_ClassName == "" )
  71.       {
  72.          TRACE( "CBubble, AfxRegisterWndClass() failed\n" );
  73.          return( FALSE );
  74.       }
  75.    }
  76.  
  77.    CRect rectangle;
  78.  
  79.    rectangle.SetRectEmpty();
  80.  
  81.    m_Created = CreateEx( 0,
  82.                          m_ClassName,
  83.                          "",
  84.                          WS_POPUP | WS_BORDER,
  85.                          rectangle.left,
  86.                          rectangle.top,
  87.                          rectangle.right,
  88.                          rectangle.bottom,
  89.                          NULL,
  90.                  (HMENU) NULL );
  91.  
  92.    if ( m_Font.GetSafeHandle() == NULL )
  93.    {
  94.       m_SetFont();
  95.    }
  96.  
  97.    return( m_Created );
  98. }
  99.  
  100. BOOL CBubble::DestroyWindow()
  101. {
  102.    m_Created = FALSE;
  103.    return( CWnd::DestroyWindow() );
  104. }
  105.  
  106. DWORD CBubble::GetHeight( void ) const
  107. {
  108.    return( m_Height );
  109. }
  110.  
  111. void CBubble::Hide( void )
  112. {
  113.    ShowWindow( SW_HIDE );
  114. }
  115.  
  116. BOOL CBubble::IsCreated( void ) const
  117. {
  118.    return( m_Created );
  119. }
  120.  
  121. void CBubble::m_SetFont( void )
  122. {
  123.    CClientDC device_context( this );
  124.  
  125.    TRY
  126.    {
  127.       LOGFONT font_attributes;
  128.  
  129.       ::ZeroMemory( &font_attributes, sizeof( font_attributes ) );
  130.  
  131.       font_attributes.lfHeight         = -::MulDiv( m_FontSize, device_context.GetDeviceCaps( LOGPIXELSY ), 72 );
  132.       font_attributes.lfCharSet        = DEFAULT_CHARSET;
  133.       font_attributes.lfQuality        = DEFAULT_QUALITY;
  134.       font_attributes.lfClipPrecision  = CLIP_LH_ANGLES | CLIP_STROKE_PRECIS;
  135.       font_attributes.lfPitchAndFamily = FF_SWISS;
  136.  
  137.       m_Font.CreateFontIndirect( &font_attributes );
  138.    }
  139.    CATCH( CResourceException, e )
  140.    {
  141.       TRACE( "CBubble, font creation failed\n" );
  142.       return;
  143.    }
  144.    END_CATCH
  145.  
  146.    CFont *old_font = device_context.SelectObject( &m_Font );
  147.  
  148.    TEXTMETRIC text_metrics;
  149.    device_context.GetTextMetrics( &text_metrics );
  150.    device_context.SelectObject( old_font );
  151.    m_Height = text_metrics.tmHeight + text_metrics.tmExternalLeading + ( 6 * GetSystemMetrics( SM_CYBORDER ) );
  152. }
  153.  
  154. void CBubble::SetFontSize( int font_size )
  155. {
  156.    m_FontSize = font_size;
  157. }
  158.  
  159. void CBubble::Show( CPoint point, const CString& string )
  160. {
  161.    Hide();
  162.    UpdateWindow();
  163.  
  164.    SetWindowText( string );
  165.  
  166.    CRect bubble;
  167.    GetWindowRect( &bubble );
  168.    CRect screen;
  169.  
  170.    ::GetWindowRect( ::GetDesktopWindow(), &screen );
  171.  
  172.    /*
  173.    ** Let's make sure the window is always visible (on screen)
  174.    */
  175.  
  176.    if ( point.y < 0 )
  177.    {
  178.       point.y = 0;
  179.    }
  180.  
  181.    if ( ( point.y + bubble.Height() ) > screen.bottom )
  182.    {
  183.       point.y = screen.bottom - ( bubble.Height() + 1 );
  184.    }
  185.  
  186.    if ( point.x < 0 )
  187.    {
  188.       point.x = abs( point.x ) - ( bubble.Width() / 2 );
  189.    }
  190.  
  191.    if ( point.x > screen.right )
  192.    {
  193.       point.x = screen.right - ( bubble.Width() + 1 );
  194.    }
  195.  
  196.    SetWindowPos( &wndTop, point.x, point.y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE );
  197.  
  198.    ShowWindow( SW_SHOWNOACTIVATE );
  199. }
  200.  
  201. BEGIN_MESSAGE_MAP( CBubble, CWnd )
  202.    ON_WM_PAINT()
  203.    ON_MESSAGE( WM_SETTEXT, OnSetText )
  204. END_MESSAGE_MAP()
  205.  
  206. void CBubble::OnPaint()
  207. {
  208.    CPaintDC device_context( this );
  209.  
  210.    CRect rectangle;
  211.  
  212.    GetClientRect( rectangle );
  213.  
  214.    CFont *old_font = device_context.SelectObject( &m_Font );
  215.    device_context.SetTextAlign( TA_CENTER );
  216.    device_context.SetBkMode( TRANSPARENT );
  217.    device_context.SetTextColor( BLACK );
  218.  
  219.    CString text;
  220.    GetWindowText( text );
  221.    CSize size = device_context.GetTextExtent( text, text.GetLength() );
  222.    device_context.TextOut( rectangle.right / 2, ( rectangle.bottom - size.cy ) / 2, text );
  223.    device_context.SelectObject( old_font );
  224. }
  225.  
  226. afx_msg LONG CBubble::OnSetText( UINT, LONG lParam )
  227. {
  228.    CRect rectangle;
  229.    GetWindowRect( rectangle );
  230.    
  231.    CClientDC device_context( this );
  232.  
  233.    CFont *old_font = device_context.SelectObject( &m_Font );
  234.    CSize size = device_context.GetTextExtent( (LPCSTR) lParam, lstrlen( (LPCSTR) lParam ) );
  235.  
  236.    rectangle.right = rectangle.left + size.cx + ( 6 * GetSystemMetrics( SM_CXBORDER ) );
  237.  
  238.    rectangle.bottom = rectangle.top + m_Height;
  239.    MoveWindow( &rectangle );
  240.    device_context.SelectObject( old_font );
  241.  
  242.    return( CWnd::Default() );
  243. }
  244.